<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Admin\Ctl;

use Srv\Apps\Apis\Account\Ctl\AccountCtl;
use Srv\Apps\Apis\Common\Ctl\StorageCtl;
use Srv\Apps\Apis\Common\DefCtl\DefStorageCategoryCtl;
use Srv\Apps\Apis\Common\IdxCtl\IdxIp;
use Srv\Apps\Proto\DTO\Admin\AdmUserAddDTO;
use Srv\Apps\Proto\DTO\Admin\AdmUserEditDTO;
use Srv\Apps\Proto\DTO\Admin\AdmUserInfoListDTO;
use Srv\Apps\Proto\Enum\YesOrNoEnum;
use Srv\Apps\Proto\VO\Admin\AdmUserInfoBasicVO;
use Srv\Apps\Proto\VO\Admin\AdmUserInfoListVO;
use Srv\Apps\Proto\VO\Admin\AdmUserInfoVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Common\CommJson;
use Srv\Libs\Common\CommTime;
use Srv\Libs\Frame\AuthData;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;

final class AdminCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write
    const FRONT_ROUTE_IDS_MUST              = [2, 4];  // 2-首页, 4-修改密码

    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param int $admUserId
     * @return array
     * getAdmUserInfoSrc
     */
    public function getAdmUserInfoSrc(int $admUserId):array
    {
        if($admUserId < 1) return [];
        $isFail         = false;
        $admUserRecord  = $this->DbAuto->getDataOne('SELECT auir_id, auir_account, auir_password, auir_name, auir_avatar, auir_gender, auir_email, auir_mobile, auir_bind, auir_bind_key, auir_sign, auir_sign_account, auir_sign_bind, auir_allow_ips, auir_super, auir_last_sign_num, auir_last_sign_time, auir_last_sign_ip, takr_ids, arlr_ids, afrt_ids, afro_ids, auir_create_time, auir_update_time FROM '.$this->DbAuto->getTableNameAll('adm_user_record').' WHERE auir_id='.$admUserId.' AND auir_delete=0', $isFail);
        if($isFail || !isset($admUserRecord['auir_id'])) return [];
        return $admUserRecord;
    }

    /**
     * @param int $admUserId
     * @return AdmUserInfoVO|null
     * getAdmUserInfo
     */
    public function getAdmUserInfo(int $admUserId):?AdmUserInfoVO
    {
        $admUserRecord  = $this->getAdmUserInfoSrc($admUserId);
        if(!isset($admUserRecord['auir_id'])) return null;
        return $this->getAdmUserInfoVO($admUserRecord);
    }

    /**
     * @param int $admUserId
     * @return AdmUserInfoBasicVO|null
     * getAdmUserInfoBasic
     */
    public function getAdmUserInfoBasic(int $admUserId):?AdmUserInfoBasicVO
    {
        $admUserRecord  = $this->getAdmUserInfoSrc($admUserId);
        if(!isset($admUserRecord['auir_id'])) return null;
        return $this->getAdmUserInfoBasicVO($admUserRecord);
    }

    /**
     * @param $auirIdList
     * @return array
     * getAdmUserInfoSrcBatch
     */
    public function getAdmUserInfoSrcBatch($auirIdList):array
    {
        if(count($auirIdList) < 1) return [];
        $isFail             = false;
        $list               = $this->DbAuto->getData('SELECT auir_id, auir_account, auir_password, auir_name, auir_avatar, auir_gender, auir_email, auir_mobile, auir_bind, auir_bind_key, auir_sign, auir_sign_account, auir_sign_bind, auir_allow_ips, auir_super, auir_last_sign_num, auir_last_sign_time, auir_last_sign_ip, takr_ids, arlr_ids, afrt_ids, afro_ids, auir_create_time, auir_update_time FROM '.$this->DbAuto->getTableNameAll('adm_user_record').' WHERE auir_id IN ('.implode(',', $auirIdList).') AND auir_delete=0', $isFail);
        if($isFail || count($list) < 1) return [];
        $listData           = [];
        foreach ($list as $item){
            $auirIdItem             = intval($item['auir_id']);
            if($auirIdItem < 1) continue;
            $listData[$auirIdItem]  = $item;
        }
        return $listData;
    }

    /**
     * @param array $auirIdList
     * @return array
     * getAdmUserInfoBasicBatch
     */
    public function getAdmUserInfoBasicBatch(array $auirIdList):array
    {
        $AdmUserInfoBasicVOList = [];
        if(count($auirIdList) < 1) return $AdmUserInfoBasicVOList;
        $admUserRecordSrcList   = $this->getAdmUserInfoSrcBatch($auirIdList);
        if(CommArray::isForeach($admUserRecordSrcList)){
            foreach ($admUserRecordSrcList as $admUserRecord){
                $auirIdItem                             = intval($admUserRecord['auir_id']);
                if($auirIdItem < 1) continue;
                $AdmUserInfoBasicVO                     = $this->getAdmUserInfoBasicVO($admUserRecord);
                if(!($AdmUserInfoBasicVO instanceof AdmUserInfoBasicVO)) continue;
                $AdmUserInfoBasicVOList[$auirIdItem]    = $AdmUserInfoBasicVO;
            }
        }
        return $AdmUserInfoBasicVOList;
    }

    /**
     * @param array $admUserRecord
     * @return AdmUserInfoBasicVO|null
     * 组装管理员基础信息
     */
    public function getAdmUserInfoBasicVO(array $admUserRecord): ?AdmUserInfoBasicVO
    {
        $admUserId          = intval($admUserRecord['auir_id']??0);
        if($admUserId < 1) return null;
        $AdmUserInfoBasicVO = new AdmUserInfoBasicVO();
        $AdmUserInfoBasicVO->setAdmUserId($admUserId);
        $AdmUserInfoBasicVO->setAdmAcc(trim($admUserRecord['auir_account']));
        $AdmUserInfoBasicVO->setName(trim($admUserRecord['auir_name']));
        $AdmUserInfoBasicVO->setAvatar(trim($admUserRecord['auir_avatar']));
        $AdmUserInfoBasicVO->setGender(intval($admUserRecord['auir_gender']));
        $AdmUserInfoBasicVO->setEmail(trim($admUserRecord['auir_email']));
        $AdmUserInfoBasicVO->setMobile(trim($admUserRecord['auir_mobile']));
        $AdmUserInfoBasicVO->setBind(YesOrNoEnum::parseValue($admUserRecord['auir_bind']));
        $AdmUserInfoBasicVO->setBindKey(trim($admUserRecord['auir_bind_key']));
        $AdmUserInfoBasicVO->setSign(YesOrNoEnum::parseValue($admUserRecord['auir_sign']));
        $AdmUserInfoBasicVO->setSignAcc(YesOrNoEnum::parseValue($admUserRecord['auir_sign_account']));
        $AdmUserInfoBasicVO->setSignBind(YesOrNoEnum::parseValue($admUserRecord['auir_sign_bind']));
        $AdmUserInfoBasicVO->setSuper(YesOrNoEnum::parseValue($admUserRecord['auir_super']));
        $IpString           = IdxIp::tag()->getIpStrByIntStr($admUserRecord['auir_last_sign_ip']);
        $AdmUserInfoBasicVO->setLastSignIp($IpString);
        $AdmUserInfoBasicVO->setLastSignNum(intval($admUserRecord['auir_last_sign_num']));
        $AdmUserInfoBasicVO->setLastSignTime(intval($admUserRecord['auir_last_sign_time']));
        return $AdmUserInfoBasicVO;
    }

    /**
     * @param array $admUserRecord
     * @return AdmUserInfoVO|null
     * 组装管理员基础信息
     */
    public function getAdmUserInfoVO(array $admUserRecord): ?AdmUserInfoVO
    {
        $admUserId          = intval($admUserRecord['auir_id']??0);
        if($admUserId < 1) return null;
        $AdmUserInfoVO      = new AdmUserInfoVO();
        $AdmUserInfoVO->setAdmUserId($admUserId);
        $AdmUserInfoVO->setAdmAcc(trim($admUserRecord['auir_account']));
        $AdmUserInfoVO->setName(trim($admUserRecord['auir_name']));
        $avatar             = trim($admUserRecord['auir_avatar']);
        $avatarUrl          = StorageCtl::tag()->getStorageUrl($avatar, true);
        $AdmUserInfoVO->setAvatar($avatarUrl);
        $AdmUserInfoVO->setGender(intval($admUserRecord['auir_gender']));
        $AdmUserInfoVO->setEmail(trim($admUserRecord['auir_email']));
        $AdmUserInfoVO->setMobile(trim($admUserRecord['auir_mobile']));
        $AdmUserInfoVO->setBind(YesOrNoEnum::parseValue($admUserRecord['auir_bind']));
        $AdmUserInfoVO->setBindKey(trim($admUserRecord['auir_bind_key']));
        $AdmUserInfoVO->setSign(YesOrNoEnum::parseValue($admUserRecord['auir_sign']));
        $AdmUserInfoVO->setSignAcc(YesOrNoEnum::parseValue($admUserRecord['auir_sign_account']));
        $AdmUserInfoVO->setSignBind(YesOrNoEnum::parseValue($admUserRecord['auir_sign_bind']));
        $AdmUserInfoVO->setSuper(YesOrNoEnum::parseValue($admUserRecord['auir_super']));
        $IpString           = IdxIp::tag()->getIpStrByIntStr($admUserRecord['auir_last_sign_ip']);
        $AdmUserInfoVO->setLastSignIp($IpString);
        $AdmUserInfoVO->setLastSignNum(intval($admUserRecord['auir_last_sign_num']));
        $AdmUserInfoVO->setLastSignTime(intval($admUserRecord['auir_last_sign_time']));
        $frontRouteIds      = CommJson::decodeArray(trim($admUserRecord['afrt_ids']));
        $frontRoleIds       = CommJson::decodeArray(trim($admUserRecord['afro_ids']));
        $frontRouteList     = [];
        $frontRouteListAll  = [];
        $roleInfoList       = [];
        $frontRouteIds      = array_merge_recursive($frontRouteIds, self::FRONT_ROUTE_IDS_MUST);
        $this->getAdminFrontRouteList($frontRoleIds, $frontRouteIds, $roleInfoList, $frontRouteList, $frontRouteListAll);
        if(count($frontRouteList) > 0) $AdmUserInfoVO->setRouteList($frontRouteList);
        if(count($frontRouteListAll) > 0) $AdmUserInfoVO->setRouteListAll($frontRouteListAll);
        if(count($roleInfoList) > 0) $AdmUserInfoVO->setRoleList($roleInfoList);
        $AdmUserInfoVO->setCreateTime(intval($admUserRecord['auir_create_time']));
        $AdmUserInfoVO->setUpdateTime(intval($admUserRecord['auir_update_time']));
        return $AdmUserInfoVO;
    }

    /**
     * @param array $roleIds
     * @param array $frontRouteIds
     * @param array $roleInfoList
     * @param array $frontRouteList
     * @param array $frontRouteListAll
     * @return bool
     * 通过前端角色Ids, 路由ids获取权限数组
     */
    public function getAdminFrontRouteList(array $roleIds, array $frontRouteIds, array &$roleInfoList, array &$frontRouteList, array &$frontRouteListAll):bool
    {
        $frontRouteIdsAll   = $frontRouteIds;
        $AuthCtl            = AuthCtl::tag();
        // 角色拥有的权限KeyId
        if(count($roleIds) > 0){
            $isFail         = false;
            $sql            = 'SELECT afrt_ids FROM '.$this->DbAuto->getTableNameAll('adm_front_role_record').' WHERE afro_id IN('.implode(',', $roleIds).') AND afro_delete=0 AND afro_status=1';
            $list           = $this->DbAuto->getData($sql, $isFail);
            if(!$isFail && CommArray::isForeach($list)){
                foreach ($list as $item){
                    $afrtIds            = array_filter(array_map('intval', CommJson::decodeArray($item['afrt_ids'])));
                    $frontRouteIdsAll   = array_keys(array_flip($frontRouteIds) + array_flip($afrtIds));  // 合并&去重
                }
            }
            $roleInfoList   = $AuthCtl->getFrontRoleInfoVOList($roleIds);
        }
        if(count($frontRouteIds) > 0) $frontRouteList = $AuthCtl->getFrontRouteVOList($frontRouteIds);
        if(count($frontRouteIdsAll) > 0) $frontRouteListAll = $AuthCtl->getFrontRouteVOList($frontRouteIdsAll);
        return true;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return AdmUserInfoListVO|null
     * getAdmUserInfoList
     */
    public function getAdmUserInfoList(Page $Page, array $whereData): ?AdmUserInfoListVO
    {
        $limitString        = $Page->getLimitString();
        $whereString        = ' WHERE auir_delete=0 ';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case AdmUserInfoListDTO::_admUserId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_id='. intval($val);
                    break;
                case AdmUserInfoListDTO::_admAcc:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_account LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case AdmUserInfoListDTO::_name:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_name LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case AdmUserInfoListDTO::_gender:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_gender='.intval($val);
                    break;
                case AdmUserInfoListDTO::_email:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_email LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case AdmUserInfoListDTO::_mobile:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_mobile LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case AdmUserInfoListDTO::_bind:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_bind='.intval($val);
                    break;
                case AdmUserInfoListDTO::_sign:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_sign='.intval($val);
                    break;
                case AdmUserInfoListDTO::_signAcc:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_sign_account='.intval($val);
                    break;
                case AdmUserInfoListDTO::_signBind:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_sign_bind='.intval($val);
                    break;
                case AdmUserInfoListDTO::_super:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'auir_super='.intval($val);
                    break;
            }
        }
        $isFail             = false;
        $sql                = 'SELECT SQL_CALC_FOUND_ROWS auir_id, auir_account, auir_password, auir_name, auir_avatar, auir_gender, auir_email, auir_mobile, auir_bind, auir_bind_key, auir_sign, auir_sign_account, auir_sign_bind, auir_allow_ips, auir_super, auir_last_sign_num, auir_last_sign_time, auir_last_sign_ip, takr_ids, arlr_ids, afrt_ids, afro_ids, auir_create_time, auir_update_time FROM '.$this->DbAuto->getTableNameAll('adm_user_record').$whereString.' ORDER BY auir_id DESC '.$limitString;
        $admUserRecordList  = $this->DbAuto->getData($sql, $isFail);
        $totalNum           = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $AdmUserInfoVOList  = [];
        if(CommArray::isForeach($admUserRecordList))foreach($admUserRecordList as $admUserRecord){
            $auirIdItem             = intval($admUserRecord['auir_id']);
            if($auirIdItem < 1) continue;
            $AdmUserInfoVO          = $this->getAdmUserInfoVO($admUserRecord);
            if(!($AdmUserInfoVO instanceof AdmUserInfoVO)) continue;
            $AdmUserInfoVOList[]    = $AdmUserInfoVO;
        }
        $AdmUserInfoListVO = new AdmUserInfoListVO();
        $AdmUserInfoListVO->setList($AdmUserInfoVOList);
        $AdmUserInfoListVO->setPage($Page->getPageVO($totalNum));
        return $AdmUserInfoListVO;
    }

    /**
     * @param array $auirIdList
     * @return array
     * getAdmUserInfoVOList
     */
    public function getAdmUserInfoBatch(array $auirIdList):array
    {
        $AdmUserInfoVOList      = [];
        if(count($auirIdList) < 1) return $AdmUserInfoVOList;
        $isFail                 = false;
        $admUserRecordList      = $this->DbAuto->getData('SELECT auir_id, auir_account, auir_password, auir_name, auir_avatar, auir_gender, auir_email, auir_mobile, auir_bind, auir_bind_key, auir_sign, auir_sign_account, auir_sign_bind, auir_allow_ips, auir_super, auir_last_sign_num, auir_last_sign_time, auir_last_sign_ip, takr_ids, arlr_ids, afrt_ids, afro_ids, auir_create_time, auir_update_time FROM '.$this->DbAuto->getTableNameAll('adm_user_record').' WHERE auir_id IN ('.implode(',', $auirIdList).') AND auir_delete=0', $isFail);
        if($isFail || count($admUserRecordList) < 1) return $AdmUserInfoVOList;
        foreach ($admUserRecordList as $admUserRecord){
            $auirIdItem         = intval($admUserRecord['auir_id']);
            if($auirIdItem < 1) continue;
            $AdmUserInfoVO      = $this->getAdmUserInfoVO($admUserRecord);
            if(!($AdmUserInfoVO instanceof AdmUserInfoVO)) continue;
            $AdmUserInfoVOList[$auirIdItem] = $AdmUserInfoVO;
        }
        return $AdmUserInfoVOList;
    }

    /**
     * @param array $setData
     * @return int
     * 新增管理员
     */
    public function admUserAdd(array $setData):int
    {
        if(count($setData) < 1) return 0;
        $setString      = '';
        foreach ($setData as $key => $val){
            switch ($key){
                case AdmUserAddDTO::_account:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_account=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserAddDTO::_password:
                    $passwordNew    = AccountCtl::tag()->getAdmUserPwd($val);
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_password=\''.$this->DbAuto->getRealEscapeString($passwordNew).'\'';
                    break;
                case AdmUserAddDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserAddDTO::_avatarKey:
                    $dsacId         = DefStorageCategoryCtl::tag()->getIdByKey(DefStorageCategoryCtl::KEY_ADM_AVATAR);
                    if($dsacId < 1) return 0;
                    $saveUrl        = StorageCtl::tag()->getStorageUrlRecord(AuthData::getLoginUserId(), $dsacId, $val);
                    if(strlen($saveUrl) < 1) return 0;
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_avatar=\''.$this->DbAuto->getRealEscapeString($saveUrl).'\'';
                    break;
                case AdmUserAddDTO::_gender:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_gender='.intval($val);
                    break;
                case AdmUserAddDTO::_email:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_email=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserAddDTO::_mobile:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_mobile=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserAddDTO::_bindKey:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_bind_key=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    if(strlen($val) > 0) $setString .= (strlen($setString) > 0 ? ', ' : '') . 'auir_bind='.YesOrNoEnum::YES_OR_NO_YES;
                    break;
                case AdmUserAddDTO::_sign:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_sign='.intval($val);
                    break;
                case AdmUserAddDTO::_signAcc:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_sign_account='.intval($val);
                    break;
                case AdmUserAddDTO::_signBind:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_sign_bind='.intval($val);
                    break;
            }
        }
        if (strlen($setString) < 1) return 0;
        $currTime       = CommTime::getTimeStamp(0);
        $isFail         = false;
        $sql            = 'INSERT INTO '.$this->DbAuto->getTableNameAll('adm_user_record').' SET '.$setString.', takr_ids=\'[]\', arlr_ids=\'[]\', afrt_ids=\'[]\', afro_ids=\'[]\', auir_delete=0, auir_create_time='.$currTime.', auir_update_time='.$currTime;
        $admUserId      = $this->DbAuto->getDataId($sql, $isFail);
        if($isFail || $admUserId < 1) return 0;
        return $admUserId;
    }

    /**
     * @param int $admUserId
     * @param array $setData
     * @return bool
     * 编辑管理员
     */
    public function admUserEdit(int $admUserId, array $setData):bool
    {
        if($admUserId < 1 || count($setData) < 1) return false;
        $setString      = '';
        $kickAdmUserOut = false;
        foreach ($setData as $key => $val){
            switch ($key){
                case AdmUserEditDTO::_account:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_account=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserEditDTO::_password:
                    $kickAdmUserOut = true;
                    $passwordNew    = AccountCtl::tag()->getAdmUserPwd($val);
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_password=\''.$this->DbAuto->getRealEscapeString($passwordNew).'\'';
                    break;
                case AdmUserEditDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserEditDTO::_avatarKey:
                    $dsacId         = DefStorageCategoryCtl::tag()->getIdByKey(DefStorageCategoryCtl::KEY_ADM_AVATAR);
                    if($dsacId < 1) return false;
                    $saveUrl        = StorageCtl::tag()->getStorageUrlRecord(AuthData::getLoginUserId(), $dsacId, $val);
                    if(strlen($saveUrl) < 1) return false;
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_avatar=\''.$this->DbAuto->getRealEscapeString($saveUrl).'\'';
                    break;
                case AdmUserEditDTO::_gender:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_gender='.intval($val);
                    break;
                case AdmUserEditDTO::_email:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_email=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserEditDTO::_mobile:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_mobile=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case AdmUserEditDTO::_bindKey:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_bind_key=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    if(strlen($val) > 0) $setString .= (strlen($setString) > 0 ? ', ' : '') . 'auir_bind='.YesOrNoEnum::YES_OR_NO_YES;
                    break;
                case AdmUserEditDTO::_sign:
                    if(intval($val) === YesOrNoEnum::YES_OR_NO_NO) $kickAdmUserOut = true;
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_sign='.intval($val);
                    break;
                case AdmUserEditDTO::_signAcc:
                    if(intval($val) === YesOrNoEnum::YES_OR_NO_NO) $kickAdmUserOut = true;
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_sign_account='.intval($val);
                    break;
                case AdmUserEditDTO::_signBind:
                    if(intval($val) === YesOrNoEnum::YES_OR_NO_NO) $kickAdmUserOut = true;
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'auir_sign_bind='.intval($val);
                    break;
            }
        }
        if(strlen($setString) < 1) return false;
        $isFail         = false;
        $currTime       = CommTime::getTimeStamp(0);
        $sql            = 'UPDATE '.$this->DbAuto->getTableNameAll('adm_user_record').' SET '.$setString.', auir_update_time='.$currTime.' WHERE auir_id='.$admUserId.' AND auir_delete=0';
        if($this->DbAuto->getDataNum($sql, $isFail) < 1 || $isFail) return false;
        if($kickAdmUserOut) $this->clearUserToken($admUserId);
        return true;
    }

    /**
     * @param int $admUserId
     * @param array $routeIdList
     * @param array $roleIdList
     * @return bool
     * admUserAuthEdit
     */
    public function admUserAuthEdit(int $admUserId, array $routeIdList, array $roleIdList):bool
    {
        if($admUserId < 1) return false;
        $takrIdList             = [];
        $AuthCtl                = AuthCtl::tag();
        if(count($routeIdList) > 0){
            $frontRouteSrcList  = $AuthCtl->getFrontRouteSrcByIdBatch($routeIdList);
            $routeIdList        = array_map('intval', array_column($frontRouteSrcList, 'afrtId'));
            foreach ($frontRouteSrcList as $item){
                if(is_array($item['takrIds']) && count($item['takrIds']) > 0){
                    $takrIdList = array_keys(array_flip($takrIdList) + array_flip($item['takrIds']));
                }
            }
        }
        if(count($roleIdList) > 0){
            $roleInfoSrcList    = $AuthCtl->getFrontRoleInfoSrcByIdBatch($roleIdList);
            $roleIdList         = array_map('intval', array_column($roleInfoSrcList, 'afroId'));
            if(count($roleInfoSrcList) > 0){
                $roleRouteIdList            = [];
                foreach ($roleInfoSrcList as $item){
                    $afrtIds                = CommJson::decodeArray($item['afrtIds']??'[]');
                    if(count($afrtIds) > 0){
                        $roleRouteIdList    = array_keys(array_flip($roleRouteIdList) + array_flip($afrtIds));
                    }
                }
                $roleFrontRouteSrcList      = $AuthCtl->getFrontRouteSrcByIdBatch($roleRouteIdList);
                $roleTakrIdList             = [];
                foreach ($roleFrontRouteSrcList as $item){
                    if(is_array($item['takrIds']) && count($item['takrIds']) > 0){
                        $roleTakrIdList     = array_keys(array_flip($roleTakrIdList) + array_flip($item['takrIds']));
                    }
                }
                if(count($roleTakrIdList) > 0){
                    $takrIdList             = array_keys(array_flip($takrIdList) + array_flip($roleTakrIdList));
                }
            }
        }
        sort($routeIdList, SORT_NUMERIC);   // 排序
        sort($roleIdList, SORT_NUMERIC);
        sort($takrIdList, SORT_NUMERIC);
        $afrtIds            = CommJson::encodeArray($routeIdList);
        $afroIds            = CommJson::encodeArray($roleIdList);
        $takrIds            = CommJson::encodeArray($takrIdList);   // 冗余系统请求Id
        $arlrIds            = '[]'; // 系统角色表空
        $currTime           = CommTime::getTimeStamp(0);
        // 更新用户权限
        $isFail             = false;
        $sql                = 'UPDATE '.$this->DbAuto->getTableNameAll('adm_user_record').' SET takr_ids=\''.$this->DbAuto->getRealEscapeString($takrIds).'\', arlr_ids=\''.$this->DbAuto->getRealEscapeString($arlrIds).'\', afro_ids=\''.$this->DbAuto->getRealEscapeString($afroIds).'\', afrt_ids=\''.$this->DbAuto->getRealEscapeString($afrtIds).'\', auir_update_time='.$currTime.' WHERE auir_id='.$admUserId.' AND auir_delete=0';
        $this->DbAuto->getDataNum($sql, $isFail);
        if($isFail) return false;
        $this->clearUserToken($admUserId);
        return true;
    }

    /**
     * @param int $admUserId
     * @return bool
     * clearUserToken
     */
    public function clearUserToken(int $admUserId):bool
    {
        if($admUserId < 1) return false;
        $currTime               = CommTime::getTimeStamp();
        $isFail                 = false;
        $tokenKeyOldList        = $this->DbAuto->getData('SELECT utnr_id, utnr_nonce, ddpt_id FROM '.$this->DbAuto->getTableNameAll('adm_user_token').' WHERE auir_id='.$admUserId.' AND utnr_delete=0 AND utnr_expire_time>='.$currTime, $isFail);
        if(!$isFail && CommArray::isForeach($tokenKeyOldList)){
            $utnrIdList         = [];
            foreach($tokenKeyOldList as $val){
                $utnrId             = intval($val['utnr_id']);
                $nonceIntVal        = intval($val['utnr_nonce']);
                if($utnrId < 1 || $nonceIntVal < 1) continue;
                $utnrIdList[]       = $utnrId;
                AuthData::delCacheTokenKeyData(AuthData::getTokenKeyByNonce($nonceIntVal), $admUserId);
            }
            if(count($utnrIdList) > 0) $this->DbAuto->query('UPDATE '.$this->DbAuto->getTableNameAll('adm_user_token').' SET utnr_delete=1, utnr_update_time='.$currTime.' WHERE utnr_id IN ('.implode(',', $utnrIdList).') AND auir_id='.$admUserId.' AND utnr_delete=0');
        }
        return true;
    }

    /**
     * @param $admUserId
     * @param string $passOld
     * @param string $passNew
     * @param string $errMsg
     * @return bool
     * admMePassEdit
     */
    public function admMePassEdit($admUserId, string $passOld, string $passNew, string &$errMsg):bool
    {
        if($admUserId < 1 || strlen($passOld) !== 40 || strlen($passNew) !== 40){
            $errMsg     = '参数错误';
            return false;
        }
        $admMeInfo      = $this->getAdmUserInfoSrc($admUserId);
        if(!isset($admMeInfo)){
            $errMsg     = '用户不存在';
            return false;
        }
        $AccountCtl     = AccountCtl::tag();
        $passOldNew     = $AccountCtl->getAdmUserPwd($passOld);
        if($passOldNew !== $admMeInfo['auir_password']){
            $errMsg     = '原密码错误';
            return false;
        }
        if(!$this->admUserEdit($admUserId, [AdmUserEditDTO::_password => $passNew])){
            $errMsg     = '更新密码失败';
            return false;
        }
        return true;
    }
}